/**
  ******************************************************************************
  * @file    IAP/src/main.c 
  * @author  MCD Application Team
  * @version V3.3.0
  * @date    10/15/2010
  * @brief   Main program body
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
  */ 

/** @addtogroup IAP
  * @{
  */

/* Includes ------------------------------------------------------------------*/
#include "common.h"
#include "SPI_Flash.h"
#include "ff.h"
#include "sFlashLoad.h"

/* Private typedef -----------------------------------------------------------*/
#define UPDATE_NONE	0
#define ROM_UPDATE	1
#define UART_UPDATE	2
#define UPDATE_OK		3
/* Private define ------------------------------------------------------------*/
#define FramewareFilePath "0:Bean.bin"
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
extern pFunction Jump_To_Application;
extern uint32_t JumpAddress;

FATFS fs;
FIL FwFile;
unsigned int br;

/* Private function prototypes -----------------------------------------------*/
static void IAP_Init(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
	u8 key;
	u8 delFlag = 0;
	u32 iapFlag = UPDATE_NONE;
	u32 i;
	
	IAP_Init();
	
	SerialPutString("\r\nLoading Bootloader ... \r\n");
	/* Flash unlock */
	FLASH_Unlock();
	/*SPI Flash Init*/
	SPI_FLASH_Init();
	
	if(f_mount(0,&fs) == FR_OK)
	{
		//mount OK
		if(f_open(&FwFile, FramewareFilePath , FA_OPEN_EXISTING | FA_READ) == FR_OK)
		{
			SerialPutString("\r\nFind Frameware File!\n");
			for(i=0 ; i<0xfffff ; i++);
			iapFlag = ROM_UPDATE;
		}
	}
	else
	{
		SerialPutString("/r/nMount Disk Fail, Please Check the Hardware!!\n");
	}
	
	if(iapFlag == ROM_UPDATE)
	{
		SerialPutString("\f");	//clear page
		SerialPutString("\r\n======================================================================");
		SerialPutString("\r\n=                   Welcome to Bean IAP Program                      =");
		SerialPutString("\r\n=                                                                    =");
		SerialPutString("\r\n=                                              By Bean Studio        =");
		SerialPutString("\r\n======================================================================");
		SerialPutString("\r\n\r\n");
		SerialPutString("Start writing ... \n");
		binUpdate();
		iapFlag = UPDATE_OK;
		
		SerialPutString("\r\nDeleting Frame File ... Press Any Key to Cancel");
		for(i=0 ; i<0x2fffff ; i++)
		{
			if(SerialKeyPressed((uint8_t*)&key))	//key pressed
			{
				SerialPutString("\r\nCanceled");
				delFlag = 1;
				break;
			}
		}
		if(!delFlag)
		{
			//delete frameware file
			SerialPutString("\r\nDeleting ... ");
			f_unlink(FramewareFilePath);
			SerialPutString("OK!");
		}
		for(i=0 ; i<0x1fffff ; i++);
	}
	
	
	if(iapFlag == UPDATE_NONE)
	{
		SerialPutString("\r\nPress Any Key to Enter the IAP Part ...");
		//for(i=0 ; i<0xfffff ; i++)
		for(i=0 ; i<0x1ffff ; i++)
		{
			if(SerialKeyPressed((uint8_t*)&key))	//key pressed
			{
				iapFlag = UART_UPDATE;
				break;
			}
		}
	}

	/* Test if Key push-button on STM3210X-EVAL Board is pressed */
	if (iapFlag == UART_UPDATE)
	{ 
		/* If Key is pressed */
		/* Execute the IAP driver in order to re-program the Flash */
		SerialPutString("\f");	//clear page
		SerialPutString("\r\n======================================================================");
		SerialPutString("\r\n=                   Welcome to Bean IAP Program                      =");
		SerialPutString("\r\n=                                                                    =");
		SerialPutString("\r\n=                                              By Bean Studio        =");
		SerialPutString("\r\n======================================================================");
		SerialPutString("\r\n\r\n");
		Main_Menu ();
	}
	/* Keep the user application running */
	if(iapFlag == UPDATE_NONE || iapFlag == UPDATE_OK)
	{
		SerialPutString("\r\n\nSwitch to User Application ... \r\n\n");
		SerialPutString("\f");
		for(i=0 ; i<0xfff ; i++);

		/* Test if user code is programmed starting from address "ApplicationAddress" */
		if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
		{ 
			/* Jump to user application */
			JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
			Jump_To_Application = (pFunction) JumpAddress;
			/* Initialize user application's Stack Pointer */
			__set_MSP(*(__IO uint32_t*) ApplicationAddress);
			Jump_To_Application();
		}
	}

	while (1)
	{}
}

/**
  * @brief  Initialize the IAP: Configure RCC, USART and GPIOs.
  * @param  None
  * @retval None
  */
void IAP_Init(void)
{
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	/* USART resources configuration (Clock, GPIO pins and USART registers) ----*/
	/* USART configured as follow:
				- BaudRate = 115200 baud  
				- Word Length = 8 Bits
				- One Stop Bit
				- No parity
				- Hardware flow control disabled (RTS and CTS signals)
				- Receive and transmit enabled
	*/
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

	/*UART Init*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
	/* Configure USART Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Configure USART Rx as input floating */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* USART configuration */
  USART_Init(USART1, &USART_InitStructure);
    
  /* Enable USART */
  USART_Cmd(USART1, ENABLE);
}

/*int SendChar(int ch)
{
	USART_SendData(USART1, (unsigned char) ch);
  while (!(USART1->SR & USART_FLAG_TXE));
	
	return ch;
}*/

/*int GetKey(void)
{
	while (!(USART1->SR & USART_FLAG_RXNE));
	return ((int)USART_ReceiveData(USART1));
}*/

#ifdef USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */

/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
